import 'package:async/async.dart';
import 'package:boss/common/common.dart';

import 'package:boss/main.dart';
import 'package:boss/models/reback_order_list_data.dart';
import 'package:boss/models/takeout_order_list_data.dart';
import 'package:boss/route/navigator_manager.dart';
import 'package:boss/ui/page/takeoutManagement/constant/takeout_status.dart';
import 'package:boss/ui/page/takeoutManagement/page/takeoutDetail/takeout_detail_page.dart';
import 'package:boss/ui/page/takeoutManagement/page/takeoutProcess/model/tab_data.dart';
import 'package:boss/ui/page/takeoutManagement/page/takeoutProcess/widget/takeout_process_tabview.dart';
import 'package:boss/ui/widget/loading/loading.dart';
import 'package:flutter/material.dart';
import 'package:hi_common/hi_common.dart';

class TakeoutProcessProvider extends ChangeNotifier {
  /*
    订单处理
   */
  final int row = Constant.rows;

  Map<int, List<dynamic>> data = {
    TakeoutStatus.NEW_ORDER: [],
    TakeoutStatus.TAKE_PICKUP: [],
    TakeoutStatus.IN_DELIVERY: [],
    TakeoutStatus.COMPLETED: [],
    TakeoutStatus.ABNORMA_ORDER: [],
    TakeoutStatus.WAIT_PICKUP: [],
    TakeoutStatus.REBACK_ORDER: [],
  };

  //新订单
  List<TakeoutOrderItem> get newOrders => data[TakeoutStatus.NEW_ORDER];

  //待取货
  List<TakeoutOrderItem> get takePickups => data[TakeoutStatus.TAKE_PICKUP];

  //配送中
  List<TakeoutOrderItem> get inDeliveries => data[TakeoutStatus.IN_DELIVERY];

  //待提货
  List<TakeoutOrderItem> get waitPickups => data[TakeoutStatus.WAIT_PICKUP];

  //已完成
  List<TakeoutOrderItem> get completeds => data[TakeoutStatus.COMPLETED];

  //异常单
  List<TakeoutOrderItem> get abnormalOrders => data[TakeoutStatus.ABNORMA_ORDER];

  //售后单
  List<RebackOrderItem> get rebackOrders => data[TakeoutStatus.REBACK_ORDER];

  List<TabData> tabs = [
    TabData('新订单', TakeoutStatus.NEW_ORDER, GlobalKey<TakeoutProcessTabViewState>()),
    TabData('待配送', TakeoutStatus.TAKE_PICKUP, GlobalKey<TakeoutProcessTabViewState>()),
    TabData('配送中', TakeoutStatus.IN_DELIVERY, GlobalKey<TakeoutProcessTabViewState>()),
    TabData('待提货', TakeoutStatus.WAIT_PICKUP, GlobalKey<TakeoutProcessTabViewState>()),
    TabData('已完成', TakeoutStatus.COMPLETED, GlobalKey<TakeoutProcessTabViewState>()),
    TabData('异常单', TakeoutStatus.ABNORMA_ORDER, GlobalKey<TakeoutProcessTabViewState>()),
    TabData('售后单', TakeoutStatus.REBACK_ORDER, GlobalKey<TakeoutProcessTabViewState>()),
  ];

  List<String> get tabNames => tabs.map((item) => item.title).toList();

  int tabIndex = 0;

  String searchWord = '';

  int newOrderCount;
  int abnormalOrderCount;
  int rebackOrderCount;

  /*
    订单处理
   */

  TakeoutOrderItem orderDetail;

  RebackOrderItem rebackOrder;

  bool isShowButtonGroup;

  Future<Result> queryTakeoutOrderList({
    @required int status,
    String input,
    int page = 1,
  }) async {
    try {
      var res = await (status == TakeoutStatus.REBACK_ORDER
          ? api.queryRebackOrders(input: input, page: page)
          : api.queryTakeOutOrderList(
              status: status,
              input: input,
              page: page,
            ));
      if (status == TakeoutStatus.REBACK_ORDER) {
        if (!res.successful()) {
          return Result.error(res.msg);
        }

        return Result.value(res.data);
      } else {
        if (!res.successful()) {
          return Result.error(res.msg);
        }

        return Result.value(res.data);
      }
    } catch (e) {
      return Result.error(e.toString());
    }
  }

  Future<Result<List>> loadTakeoutOrderList({@required int status}) async {
    var page = data[status].length ~/ row + 1;

    var result = await queryTakeoutOrderList(
      status: status,
      input: searchWord,
      page: page,
    );

    _setData(status, result, false);

    return result.isError ? result : Result.value(result.asValue.value.items);
  }

  Future<Result<List>> refreshTakeoutOrderList({@required int status}) async {
    var result = await queryTakeoutOrderList(
      status: status,
      input: searchWord,
      page: 1,
    );

    _setData(status, result, true);

    return result.isError ? result : Result.value(result.asValue.value.items);
  }

  _setData(int status, Result result, bool isRefresh) {
    if (result.isError) return;

    var orders = result.asValue.value.items;
    var count = result.asValue.value.total;

    isRefresh ? data[status] = orders : data[status].addAll(orders);

    if (status == TakeoutStatus.NEW_ORDER) newOrderCount = count;

    if (status == TakeoutStatus.REBACK_ORDER) rebackOrderCount = count;

    if (status == TakeoutStatus.ABNORMA_ORDER) abnormalOrderCount = count;

    notifyListeners();
  }

  Future<bool> getOrder(String takeOutId, int status) async {
    try {
      showLoadingToast();

      var res = await api.getTakeOutOrder(takeOutId);

      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      toast('接单成功');

      newOrders.removeWhere((item) => item.takeOutId == takeOutId);
      newOrderCount -= 1;

      notifyListeners();

      if (NavigatorManager.instance.currentRoute.settings.name == TakeoutDetailPage.pageName) {
        Navigator.pop(GlobalPageContext.instance.context);
      }

      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  Future<bool> rejectOrder(String takeOutId) async {
    try {
      showLoadingToast();

      var res = await api.rejectTakeOutOrder(takeOutId);

      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      toast('已拒单');

      newOrders.removeWhere((item) => item.takeOutId == takeOutId);
      newOrderCount -= 1;
      notifyListeners();

      if (NavigatorManager.instance.currentRoute.settings.name == TakeoutDetailPage.pageName) {
        Navigator.pop(GlobalPageContext.instance.context);
      }

      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  Future<bool> tip(TakeoutOrderItem order, int tip) async {
    try {
      showLoadingToast();

      var res = await api.increaseTips(order.takeOutId, tip);

      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      toast('加小费成功');

      order.tip += tip;
      notifyListeners();

      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  Future<bool> picked(String takeOutId, String pickupCode) async {
    try {
      showLoadingToast();

      var res = await api.userPickup({'takeOutId': takeOutId, 'pickupCode': null});

      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      toast('客户取餐成功');

      (data[TakeoutStatus.WAIT_PICKUP] ?? []).removeWhere((item) => item.takeOutId == takeOutId);
      notifyListeners();

      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  //未处理
  agreeAbnormal(TakeoutOrderItem order) async {
    try {
      showLoadingToast();

      var res = await api.userPickup({'takeOutId': order.takeOutId});

      if (!res.successful()) {
        toast(res.msg);
        return;
      }

      toast('客户取餐成功');

      order.takeOutStatus = TakeoutStatus.ORDER_COMPUTED;
      notifyListeners();
    } catch (e) {
      toast(e.toString());
    } finally {
      hideLoadingToast();
    }
  }

  removeOrderByStatus(int stauts) {}

  //同意退款
  Future<bool> agreeRefund({
    String refundId,
    String takeOutId,
    int status,
    int backDeliveryType,
  }) async {
    try {
      showLoadingToast();

      var res = await api.agreeRefund({
        'refundId': refundId,
        'takeOutId': takeOutId,
        'backDeliveryType': backDeliveryType,
      });

      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      toast('订单已退款');

      data[status].removeWhere((item) => takeOutId == null ? item.refundId == refundId : item.takeOutId == takeOutId);
      subOrderCountByStatus(status);

      notifyListeners();

      if (NavigatorManager.instance.currentRoute.settings.name == TakeoutDetailPage.pageName) {
        Navigator.pop(GlobalPageContext.instance.context);
      }

      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  //拒绝退款
  Future<bool> rejectRefund({String refundId, String takeOutId, String reason, int status}) async {
    try {
      if (reason.length == 0) {
        toast('请输入拒绝理由反馈顾客');
        return false;
      }

      showLoadingToast();

      var res = await api.rejectRefund({
        'refundId': refundId,
        'rejectDesc': reason,
        'takeOutId': takeOutId,
      });

      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      toast('订单已拒绝退款');

      data[status].removeWhere((item) {
        if (takeOutId == null) {
          return item.refundId == refundId;
        }

        return item.takeOutId == takeOutId;
      });
      subOrderCountByStatus(status);
      notifyListeners();

      if (NavigatorManager.instance.currentRoute.settings.name == TakeoutDetailPage.pageName) {
        Navigator.pop(GlobalPageContext.instance.context);
      }
      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  //同意取消配送
  Future<bool> agreeCancelDelivery(String takeOutId) async {
    try {
      showLoadingToast();

      var res = await api.agreeCancelDelivery({'takeOutId': takeOutId});

      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      toast('您已同意取消配送，订单将自动回到待取货状态下未接单部分重新发起第三方配送订单');

      abnormalOrders.removeWhere((item) => item.takeOutId == takeOutId);
      notifyListeners();

      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  //拒绝取消配送
  Future<bool> rejectCancelDelivery(String takeOutId) async {
    try {
      showLoadingToast();

      var res = await api.rejectCancelDelivery({'takeOutId': takeOutId});

      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      toast('您已拒绝取消配送，订单将自动回到配送中状态下继续配送');

      abnormalOrders.removeWhere((item) => item.takeOutId == takeOutId);
      notifyListeners();

      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  //查询列表数量
  queryTakeoutOrderCount() async {
    try {
      var res = await api.queryTakeoutOrderCount();
      if (!res.successful()) {
        toast(res.msg);
        return;
      }
      newOrderCount = res.data.newOrderCount;
      abnormalOrderCount = res.data.failedOrderCount;
      rebackOrderCount = res.data.refundOrderCount;
      notifyListeners();
    } catch (e) {
      toast(e.toString());
    }
  }

  resetData() {
    data = {
      TakeoutStatus.NEW_ORDER: [],
      TakeoutStatus.TAKE_PICKUP: [],
      TakeoutStatus.IN_DELIVERY: [],
      TakeoutStatus.COMPLETED: [],
      TakeoutStatus.ABNORMA_ORDER: [],
      TakeoutStatus.REBACK_ORDER: [],
      TakeoutStatus.WAIT_PICKUP: [],
    };

    tabIndex = 0;

    searchWord = '';

    newOrderCount = 0;
    rebackOrderCount = 0;
    abnormalOrderCount = 0;
  }

  Future<bool> completeTakeoutOrder(String takeOutId) async {
    try {
      showLoadingToast();

      var res = await api.completeTakeoutOrder({'takeOutId': takeOutId});
      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      toast('订单处理成功');

      abnormalOrders.removeWhere((item) => item.takeOutId == takeOutId);
      abnormalOrderCount -= 1;

      notifyListeners();

      return true;
    } catch (e) {
      toast(e.toString());

      return false;
    } finally {
      hideLoadingToast();
    }
  }

  subOrderCountByStatus(int status) {
    if (status == TakeoutStatus.NEW_ORDER) newOrderCount -= 1;

    if (status == TakeoutStatus.ABNORMA_ORDER) abnormalOrderCount -= 1;

    if (status == TakeoutStatus.REBACK_ORDER) rebackOrderCount -= 1;
  }

  int getCountByStatus(int status) {
    if (status == TakeoutStatus.NEW_ORDER) return newOrderCount;

    if (status == TakeoutStatus.ABNORMA_ORDER) return abnormalOrderCount;

    if (status == TakeoutStatus.REBACK_ORDER) return rebackOrderCount;

    return 0;
  }

  Future<bool> storeRefund({
    String takeOutId,
    int status,
    List<TakeOutOrderDetails> orderDetailList,
    String reason,
    int type,
  }) async {
    try {
      showLoadingToast();

      var res = await api.storeRefund({
        'takeOutId': takeOutId,
        'applyRefundReason': reason,
        'orderDetailIdList': orderDetailList.map((item) => item.id).toList(),
        'type': type,
      });

      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      toast('退款成功');

      if (type == 0) {
        subOrderCountByStatus(status);
        data[status].removeWhere((item) => item.takeOutId == takeOutId);
        notifyListeners();
      } else {
        orderDetailList.forEach((item) {
          item.status = 1;
        });
        notifyListeners();
      }

      if (NavigatorManager.instance.currentRoute.settings.name == TakeoutDetailPage.pageName) {
        Navigator.pop(GlobalPageContext.instance.context);
      }
      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }

  Future<bool> cancelDelivery(String takeOutId) async {
    try {
      showLoadingToast();

      var res = await api.cancelDelivery(takeOutId);
      if (!res.successful()) {
        toast(res.msg);
        return false;
      }

      toast('取消配送成功');

      var find = takePickups.firstWhere((item) => item.takeOutId == takeOutId, orElse: () => null);
      if (find != null) {
        find.systemOrderStatus = TakeoutStatus.TAKE_PICKUP;
        find.takeOutStatus = TakeoutStatus.RECEIVE_ORDER;
        notifyListeners();
      }

      return false;
    } catch (e) {
      toast(e.toString());
      return false;
    } finally {
      hideLoadingToast();
    }
  }
}
